package com.example.srm.project.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.srm.auth.anno.Authority;
import com.example.srm.common.controller.BaseController;
import com.example.srm.constant.FundConstant;
import com.example.srm.constant.ProjectConstant;
import com.example.srm.constant.ProjectStatusConstant;
import com.example.srm.domain.TFund;
import com.example.srm.domain.TProject;
import com.example.srm.domain.TUser;
import com.example.srm.domain.vo.Member;
import com.example.srm.domain.vo.PageView;
import com.example.srm.domain.vo.Result;
import com.example.srm.project.mapper.TProjectMapper;
import com.example.srm.project.service.TFundService;
import com.example.srm.project.service.TProjectService;
import com.sun.net.httpserver.HttpContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author pfk
 * @creatTime 2021/11/29 11:34
 * @describe    项目操作
 * TODO query方法的废弃项未设置不展示
 */
@RestController
@RequestMapping("/project")
@Slf4j
@CrossOrigin
public class TProjectController extends BaseController<TProjectService, TProject> {

    @Autowired
    private TProjectService projectService;
    @Autowired
    private TProjectMapper projectMapper;
    @Autowired
    private TFundService fundService;

    /**
     * 多条件分页查询
     */
    @RequestMapping(value = "/query1",method = RequestMethod.GET)
    @Authority(auth = "account:project:list")
    public Result query(Integer page, Integer pageSize, String level,String college,String subject,String achievementType,String userName){
        //校验参数是否合法
        if (page==null||page<0){
            page=1;
        }
        if (pageSize==null||pageSize<=0){
            pageSize=10;
        }

        Page<TProject> tPage;
        QueryWrapper<TProject> queryWrapper = new QueryWrapper<TProject>();
        if (level!=null&&level!=""){
            queryWrapper.eq(ProjectConstant.level,level);
            log.info("level-->"+level);
        }
        if (college!=null&&college!=""){
            queryWrapper.eq(ProjectConstant.college,college);
            log.info("college-->"+college);

        }
        if (subject!=null&&subject!=""){
            queryWrapper.eq(ProjectConstant.subject,subject);
            log.info("subject-->"+subject);
        }
        if (achievementType!=null&&achievementType!=""){
            queryWrapper.eq(ProjectConstant.achievementType,achievementType);
            log.info("achievementType-->"+achievementType);
        }
        if ("-1".equals(userName)){
            //获取上下文
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request = sra.getRequest();
            TUser userinfo = (TUser) request.getSession().getAttribute("USERINFO");
            queryWrapper.eq(ProjectConstant.userName,userinfo.getUserName());
            log.info("userName-->"+userName);
        }
        tPage = projectMapper.selectPage(new Page<TProject>(page,pageSize),queryWrapper);
        List<TProject> records = tPage.getRecords();
        records.forEach(e->{
            String projectStatusName = ProjectStatusConstant.getByCode(e.getStatus1()).getName();
            e.setStatus(projectStatusName);
        });
        PageView<TProject> pageView = new PageView<TProject>()
                .setRows(records)
                .setTotalCount(tPage.getTotal())
                .setTotalPage(new Integer(tPage.getPages()+""));
        return new Result().setData(pageView).setSuccess(true);
    }


    /**
     * 删除项目
     * @param id
     * @return
     */
    @Override
    @Transactional
    @Authority(auth = "account:project:delete")
    public Result delete(String id) {
        try {
            TProject t = projectService.getById(id);
            if (t==null) {
                return new Result().setMsg("删除失败，实例不存在");
            }

           if (ProjectStatusConstant.NOT_DECLARED.getCode()!=t.getStatus1()){
               return new Result().setMsg("当前状态不能删除");
           }

            HashMap<String, Object> map = new HashMap<>();
            map.put(FundConstant.projectId,id);
            boolean removeByMap = fundService.removeByMap(map);
            boolean remove = baseIService.removeById(id);
        }catch (Exception e){
            log.error("删除项目失败",e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new Result().setMsg("删除错误，"+e);
        }
        return new Result().setSuccess(true);
    }

    /**
     * 新增项目
     * @param tProject
     * @param request
     * @return
     * @throws Exception
     */
    @Override
    @Transactional
    @Authority(auth = "account:project:add")
    public Result save(@RequestBody TProject tProject, HttpServletRequest request) throws Exception {
        System.out.println("================"+tProject);
        try {
            beforeSave(tProject);
            //补充完善项目信息
            TUser userinfo = (TUser) request.getSession().getAttribute("USERINFO");
            if (userinfo==null){return new Result().setMsg("你还没有登录");}

            if (!userinfo.getUserName().equals(tProject.getUserName())) {
                return new Result().setMsg("科研项目负责人必须是当前用户");
            }
            tProject.setCreatedUser(userinfo.getUserName())//申请人
                    .setMemberJsons(JSONObject.toJSONString(tProject.getMembers()))//项目成员
                    .setStatus1(ProjectStatusConstant.NOT_DECLARED.getCode())//状态
                    .setBeginTime(new Date())//开始时间
                    .setCanConclude(true)//结题
                    .setCanApplication(true)//申请
                    .setCanUpdate(true);//变更
            boolean saveProject = baseIService.save(tProject);
            List<TFund> funds = tProject.getFunds()
                    .stream()
                    .filter(e->e.getNumber()!=null)//过滤掉无效资金
                    .map(e->e.setProjectId(tProject.getId()))
                    .collect(Collectors.toList());
            boolean saveFunds = fundService.saveBatch(funds);
        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("保存失败",e);
            return new Result().setMsg("保存失败，请检查参数是否合法."+e.getMessage());
        }
        return new Result().setSuccess(true);
    }

    /**
     * 更新项目
     * @param tProject
     * @return
     * @throws Exception
     */
    @Override
    @Authority(auth = "account:project:update")
    @Transactional
    public Result update(@RequestBody TProject tProject,HttpServletRequest request) throws Exception {
        try {
            System.out.println(tProject);
            //判断修改的角色是否存在
            beforeUpdate(tProject);
            TUser userinfo = (TUser) request.getSession().getAttribute("USERINFO");
            if (userinfo==null){return new Result().setMsg("你还没有登录");}

            if (!userinfo.getUserName().equals(tProject.getUserName())) {
                return new Result().setMsg("科研项目负责人必须是当前用户");
            }
            //将项目状态改为草稿
            tProject.setStatus1(ProjectStatusConstant.NOT_DECLARED.getCode());
            //修改项目
            boolean updateById = baseIService.updateById(tProject);
            List<TFund> funds =new ArrayList<>();
            for (int i =0;i< tProject.getFunds().size();i++) {
                tProject.getFunds().get(i).setProjectId(tProject.getId());
                funds.add(tProject.getFunds().get(i));
            }
            /**
             * 判断传入资金是否是null。null-->删除原来的资金；不为null-->新增或修改资金
             */
            if (tProject.getFunds() == null){
                HashMap<String, Object> map = new HashMap<>();
                map.put(FundConstant.projectId,tProject.getId());
                fundService.removeByMap(map);
            }else {
                //修改或更新资金
                boolean saveOrUpdateBatch = fundService.saveOrUpdateBatch(funds);
            }

        }catch (Exception e){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.error("修改失败",e);
            return new Result().setMsg("修改失败，"+e.getMessage());
        }
        return new Result().setSuccess(true);
    }

    /**
     * 根据id查询
     * @param id
     * @return
     */
    @Override
    @Authority(auth = "account:project:detail")
    public Result findById(String id) {
        TProject t = baseIService.getById(id);
        //设置member json字符串为对象集合
        List<Member> members = JSONObject.parseArray(t.getMemberJsons(), Member.class);
        t.setMembers(members);
        HashMap<String, Object> map = new HashMap<>();
        map.put(FundConstant.projectId,id);
        List<TFund> tFunds = fundService.listByMap(map);
        t.setFunds(tFunds);
        return new Result().setData(t).setSuccess(true);
    }



    /**
     * 保存前的操作
     * @param tProject
     * @throws Exception
     */
    @Override
    public void beforeSave(TProject tProject) throws Exception {
        TProject one = projectService.getOne(new QueryWrapper<TProject>().eq(ProjectConstant.name, tProject.getName()));
        if (one!=null){throw new RuntimeException("项目名称已经存在，请更换");}
    }

    /**
     * 更新前操作
     * @param tProject
     * @throws Exception
     */
    @Override
    public void beforeUpdate(TProject tProject) throws Exception {
        //判断修改的实例是否存在
        TProject project = projectService.getOne(new QueryWrapper<TProject>().eq(ProjectConstant.id, tProject.getId()));
        if (project==null) {
            throw  new RuntimeException("项目实例"+tProject.getName()+"不存在");
        }
        int nameProject = projectService.count(new QueryWrapper<TProject>().notIn(ProjectConstant.id,tProject.getId()).eq(ProjectConstant.name, tProject.getName()));
        if (nameProject>=1) {
            throw  new RuntimeException("项目名"+tProject.getName()+"已经存在");
        }
    }
}
